#include "stdafx.h"
#include "StatusClass.h"
#include "ImmStuff.h"
#include "ImmData.h"
#include "CompAndCandWnd.h"
#include "GlobalData.h"

#define TIMEID            1
#define TIMEOUT           600
#define BITMAPX           20
#define BITMAPY           20
#define BITMAPCHINESEDES  60
#define BITMAPFULLDES     80
#define BITMAPPUNCTDES    100
#define BITMAPCHINESESRC  60
#define BITMAPFULLSRC     100
#define BITMAPPUNCTSRC    140

#define BUTTONMENU        0x01
#define BUTTONPY          0x02
#define BUTTONCHINESE     0x04
#define BUTTONFULL        0x08
#define BUTTONPUNCT       0x10
#define BUTTONPUSH        0x8000

HBITMAP StatusClass::hBmpStatus = NULL;

BOOL StatusClass::Register(HINSTANCE hInstance)
{
	WNDCLASSEX wc;
	//
    // register class of status window.
    //
    wc.cbSize         = sizeof(WNDCLASSEX);
    wc.style          = CS_PYGINPUT | CS_IME;
    wc.lpfnWndProc    = StatusClassWndProc;
    wc.cbClsExtra     = 0;
    wc.cbWndExtra     = UICHILDEXTRASIZE;
    wc.hInstance      = hInstance;
    wc.hCursor        = LoadCursor(NULL,IDC_ARROW );
    wc.hIcon          = NULL;
    wc.lpszMenuName   = NULL;
    wc.lpszClassName  = StatusClassName;
    wc.hbrBackground  = NULL;
    wc.hIconSm        = NULL;
	
    if( !RegisterClassEx( (LPWNDCLASSEX)&wc ) )
        return FALSE;
	
    return TRUE;
}

VOID StatusClass::UnRegister(HINSTANCE hInstance)
{
	UnregisterClass(StatusClassName,hInstance);
}

VOID StatusClass::Paint(HWND hStatusWnd,HDC hDC,DWORD dwButton)
{

    HIMC hIMC;
    LPINPUTCONTEXT lpIMC;
    HDC hMemDC;
    HBITMAP hBmpOld;
    HWND hSvrWnd;

    hSvrWnd = (HWND)GetWindowLong(hStatusWnd,FIGWL_SVRWND);

    if (hIMC = (HIMC)GetWindowLong(hSvrWnd,IMMGWL_IMC))
    {
        lpIMC = ImmLockIMC(hIMC);
        hMemDC = CreateCompatibleDC(hDC);
        hBmpOld = (HBITMAP)SelectObject(hMemDC,hBmpStatus);

		if( (dwButton & BUTTONMENU) || !dwButton){
			BitBlt(hDC,0,0,BITMAPX,BITMAPY,hMemDC,0,0,SRCCOPY);
		}

		if( (dwButton & BUTTONPY) || !dwButton){
			if( dwButton & BUTTONPUSH)
				BitBlt(hDC,BITMAPX,0,BITMAPX*2,BITMAPY,hMemDC,BITMAPX,BITMAPY,SRCCOPY);
			else
				BitBlt(hDC,BITMAPX,0,BITMAPX*2,BITMAPY,hMemDC,BITMAPX,0,SRCCOPY);
		}

		if( (dwButton & BUTTONCHINESE) || !dwButton){
			if(lpIMC->fOpen){
				if( dwButton & BUTTONPUSH)
					BitBlt(hDC,BITMAPCHINESEDES,0,BITMAPX,BITMAPY,hMemDC,BITMAPCHINESESRC,BITMAPY,SRCCOPY);
				else
					BitBlt(hDC,BITMAPCHINESEDES,0,BITMAPX,BITMAPY,hMemDC,BITMAPCHINESESRC,0,SRCCOPY);
			}
			else{
				if( dwButton & BUTTONPUSH)
					BitBlt(hDC,BITMAPCHINESEDES,0,BITMAPX,BITMAPY,hMemDC,BITMAPCHINESESRC + BITMAPX,BITMAPY,SRCCOPY);
				else
					BitBlt(hDC,BITMAPCHINESEDES,0,BITMAPX,BITMAPY,hMemDC,BITMAPCHINESESRC + BITMAPX,0,SRCCOPY);
			}
		}

		if( (dwButton & BUTTONFULL) || !dwButton){
				if( dwButton & BUTTONPUSH)
					BitBlt(hDC,BITMAPFULLDES,0,BITMAPX,BITMAPY,hMemDC,BITMAPFULLSRC + BITMAPX,BITMAPY,SRCCOPY);
				else
					BitBlt(hDC,BITMAPFULLDES,0,BITMAPX,BITMAPY,hMemDC,BITMAPFULLSRC + BITMAPX,0,SRCCOPY);
		}

		if( (dwButton & BUTTONPUNCT) || !dwButton){			
			if( dwButton & BUTTONPUSH)
				BitBlt(hDC,BITMAPPUNCTDES,0,BITMAPX,BITMAPY,hMemDC,BITMAPPUNCTSRC + BITMAPX,BITMAPY,SRCCOPY);
			else
				BitBlt(hDC,BITMAPPUNCTDES,0,BITMAPX,BITMAPY,hMemDC,BITMAPPUNCTSRC + BITMAPX,0,SRCCOPY);
		}

		SelectObject(hMemDC,hBmpOld);
        DeleteDC(hMemDC);
        ImmUnlockIMC(hIMC);
    }
}
DWORD StatusClass::CheckButtonPos( HWND hStatusWnd, LPPOINT lppt)
{
    POINT pt;
    RECT rc;
	DWORD dwButton = 0;

    if (lppt)
    {
        pt = *lppt;
        ScreenToClient(hStatusWnd,&pt);
        GetClientRect(hStatusWnd,&rc);
        if (!PtInRect(&rc,pt))
            return 0;

		if(pt.x < BITMAPX) {
			//dwButton |= BUTTONMENU;
			dwButton |= BUTTONPY;
		}
		else if (pt.x < BITMAPCHINESEDES) {
			dwButton |= BUTTONPY;
		}
		else if (pt.x < BITMAPFULLDES) {
			dwButton |= BUTTONCHINESE;
		}
		else if (pt.x < BITMAPPUNCTDES) {
			dwButton |= BUTTONFULL;
		}
		else if (pt.x < BITMAPPUNCTDES + BITMAPX) {
			dwButton |= BUTTONPUNCT;
		}
	}
    return dwButton;
}

VOID StatusClass::CreateWnd(HWND hUIWnd, LPUIEXTRA lpUIExtra)
{
	if (!IsWindow(lpUIExtra->uiStatus.hWnd))
    {
		RECT screenrc;
		HKEY hKey;
		DWORD dwPosition,dwData=sizeof(DWORD);
		BOOL fFlag=TRUE;

		lpUIExtra->uiStatus.sz.cx = BITMAPX * 6 ;
		lpUIExtra->uiStatus.sz.cy = BITMAPY ;

		if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,REG_PATH,0,KEY_READ,&hKey) == ERROR_SUCCESS )
		{
			if( RegQueryValueEx( hKey,_T("Position"),NULL,NULL,(LPBYTE)&dwPosition,&dwData) == ERROR_SUCCESS )
			{
				lpUIExtra->uiStatus.pt.x = (int)(short) LOWORD(dwPosition);
				lpUIExtra->uiStatus.pt.y = (int)(short) HIWORD(dwPosition);
				fFlag = FALSE;
			}
			RegCloseKey(hKey);
		}

		if(fFlag){
			SystemParametersInfo(SPI_GETWORKAREA,0,&screenrc,0);

			lpUIExtra->uiStatus.pt.x = screenrc.left + 10;
			lpUIExtra->uiStatus.pt.y = screenrc.bottom - lpUIExtra->uiStatus.sz.cy - 5;
		}

		lpUIExtra->uiStatus.hWnd = CreateWindowEx(0,StatusClassName,NULL,
                            WS_DISABLED | WS_POPUP,
                            lpUIExtra->uiStatus.pt.x,
                            lpUIExtra->uiStatus.pt.y,
							lpUIExtra->uiStatus.sz.cx,
							lpUIExtra->uiStatus.sz.cy,
                            hUIWnd,NULL,ImmStuff::hInst,NULL);
		SetWindowLong(lpUIExtra->uiStatus.hWnd,FIGWL_SVRWND,(DWORD)hUIWnd);
	}
	ShowWindow(lpUIExtra->uiStatus.hWnd,SW_SHOWNOACTIVATE);
    return;
}

VOID StatusClass::UpdateWnd(LPUIEXTRA lpUIExtra)
{
    if (IsWindow(lpUIExtra->uiStatus.hWnd)) {
		InvalidateRect(lpUIExtra->uiStatus.hWnd,NULL,TRUE);
	}
}

LRESULT WINAPI StatusClassWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static BOOL  fCanMove = FALSE;
    static POINT ptdif;
    static RECT  drc;
    static SIZE  sz;
	static DWORD dwButton;

    DWORD        dwT;
    POINT        pt;
	HDC          hDC;
	HKEY         hKey,hChildKey;
	DWORD        dwDisposition;

	hDC = GetDC(hWnd);
    switch (message)
    {
        case WM_CREATE:
			StatusClass::hBmpStatus = LoadBitmap(ImmStuff::hInst,MAKEINTRESOURCE(IDB_STATUSBG));
            break;

        case WM_PAINT:
			{
			    PAINTSTRUCT ps;
			    HDC hPaintDC;
				hPaintDC = BeginPaint(hWnd,&ps);
		        StatusClass::Paint(hWnd,hPaintDC,0);
				EndPaint(hWnd,&ps);
			    break;
			}

		case WM_TIMER:
			KillTimer(hWnd,TIMEID);
			SetCursor(LoadCursor(NULL,IDC_SIZEALL));
			fCanMove = TRUE;
			dwButton &= ~BUTTONPUSH;
			StatusClass::Paint(hWnd,hDC,dwButton);
			break;

        case WM_SETCURSOR:
			if ( HIWORD(lParam) == WM_LBUTTONDOWN ) {
				SetCapture(hWnd);
				GetCursorPos(&pt);
				GetWindowRect(hWnd,&drc);
				ptdif.x = pt.x - drc.left;
				ptdif.y = pt.y - drc.top;
				sz.cx = drc.right - drc.left;
				sz.cy = drc.bottom - drc.top;
				SetWindowLong(hWnd,FIGWL_MOUSE,FIM_CAPUTURED);

				dwButton = StatusClass::CheckButtonPos(hWnd, &pt);
				dwButton |= BUTTONPUSH;
				StatusClass::Paint(hWnd,hDC,dwButton);

				if( dwButton & BUTTONPY)
					SetTimer(hWnd,TIMEID,1,NULL);
				else
					SetTimer(hWnd,TIMEID,TIMEOUT,NULL);
			}
			else 
				return DefWindowProc(hWnd,message,wParam,lParam);
			break;

        case WM_LBUTTONUP:
			KillTimer(hWnd,TIMEID);
			ReleaseCapture();
			if( fCanMove ) {
				dwT = GetWindowLong(hWnd,FIGWL_MOUSE);
				if (dwT & FIM_MOVED) {
					CompAndCandWnd::DrawUIBorder(&drc);
					GetCursorPos( &pt );
					MoveWindow(hWnd,pt.x - ptdif.x,
							pt.y - ptdif.y,
							sz.cx,
							sz.cy,TRUE);
				}
				SetCursor(LoadCursor(NULL,IDC_ARROW));
			}
			else{
				if( dwButton & BUTTONCHINESE ) {
				    HWND hSvrWnd;
					HIMC hIMC;
					LPINPUTCONTEXT lpIMC;

					hSvrWnd = (HWND)GetWindowLong(hWnd,FIGWL_SVRWND);
					hIMC = (HIMC)GetWindowLong(hSvrWnd,IMMGWL_IMC);
			        lpIMC = ImmLockIMC(hIMC);
					if(lpIMC->fOpen) {
						lpIMC->fOpen=FALSE;
					}
					else lpIMC->fOpen=TRUE;
				}
				if(dwButton & BUTTONFULL)
				{
					DialogBox(ImmStuff::hInst,MAKEINTRESOURCE(IDD_CONFIG),NULL,ConfigDialogProc);
				}
				if(dwButton & BUTTONPUNCT)
				{
					DialogBox(ImmStuff::hInst,MAKEINTRESOURCE(IDD_ABOUT),NULL,AboutDialogProc);
				}
				dwButton &= ~BUTTONPUSH;
				StatusClass::Paint(hWnd,hDC,dwButton);
			}

			SetWindowLong(hWnd,FIGWL_MOUSE,0);
			fCanMove = FALSE;
			break;
        
        case WM_MOUSEMOVE:
			if( fCanMove ) {
				dwT = GetWindowLong(hWnd,FIGWL_MOUSE);
				if (dwT & FIM_MOVED) {
					CompAndCandWnd::DrawUIBorder(&drc);
					GetCursorPos( &pt );
					drc.left   = pt.x - ptdif.x;
					drc.top    = pt.y - ptdif.y;
					drc.right  = drc.left + sz.cx;
					drc.bottom = drc.top + sz.cy;
					CompAndCandWnd::DrawUIBorder(&drc);
				}
				else if (dwT & FIM_CAPUTURED)
				{
					CompAndCandWnd::DrawUIBorder(&drc);
					SetWindowLong(hWnd,FIGWL_MOUSE,dwT | FIM_MOVED);
				}
			}
			break;

        case WM_DESTROY:
			DeleteObject(StatusClass::hBmpStatus);
            break;

		case WM_MOVE:
			if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE,
				_T("Software"),
				0,
				KEY_READ,
				&hKey) == ERROR_SUCCESS ){
				
				if( RegCreateKeyEx( hKey,
					REG_FOLDER,
					0,
					NULL,
					REG_OPTION_NON_VOLATILE ,
					KEY_ALL_ACCESS ,
					NULL,
					&hChildKey,
					&dwDisposition ) == ERROR_SUCCESS) {
						RegSetValueEx(hChildKey,
							_T("Position"),
							0,
							REG_DWORD,
							(LPBYTE)&lParam,
							sizeof(DWORD));
					RegCloseKey(hChildKey);
				}
				
				RegCloseKey(hKey);
			}
			break;

        default:
            if (!ImmData::IsIMEMessage(message))
                return DefWindowProc(hWnd,message,wParam,lParam);
            break;
    }

	ReleaseDC(hWnd,hDC);
    return 0;
}
BOOL WINAPI AboutDialogProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
	switch(message)
	{
	case WM_INITDIALOG:
		SetDlgItemText(hWnd,IDC_EDIT1,GlobalData::GetInstance()->GetHelpTxt().c_str());
	case WM_COMMAND:
		switch(wParam)
		{
		case IDC_ABOUT_OK:
			EndDialog(hWnd,TRUE);
			break;
		default:
			break;
		}
		break;
	default:
		break;
	}
	return FALSE;
}
BOOL WINAPI ConfigDialogProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
	HKEY hKey,hChildKey;
	DWORD dwConvSet;
	DWORD dwData = sizeof(DWORD);
	DWORD dwDisposition;

	switch(message)
	{
	case WM_INITDIALOG:
		if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,REG_PATH,0,KEY_READ,&hKey) == ERROR_SUCCESS ){
				if( RegQueryValueEx( hKey,_T("ConversionSet"),NULL,NULL,(LPBYTE)&dwConvSet,&dwData) == ERROR_SUCCESS )
				{
					CheckDlgButton(hWnd,IDC_CHECK2,(!(dwConvSet & STRUCT_CODE_NORMAL)) ? BST_CHECKED :BST_UNCHECKED );
					CheckDlgButton(hWnd,IDC_CHECK3,(dwConvSet & STRUCT_CODE_NORMAL) ? BST_CHECKED :BST_UNCHECKED );
					CheckDlgButton(hWnd,IDC_CHECK4,(dwConvSet & BASECODE_FREQ_FIRST) ? BST_CHECKED :BST_UNCHECKED );
					CheckDlgButton(hWnd,IDC_CHECK5,(!(dwConvSet & BASECODE_FREQ_FIRST)) ? BST_CHECKED :BST_UNCHECKED );
				}
				RegCloseKey(hKey);
		}
		break;

	case WM_COMMAND:
		switch(wParam)
		{
		case IDC_CHECK2:
			if(IsDlgButtonChecked(hWnd,IDC_CHECK3) == BST_CHECKED)
			{
				CheckDlgButton(hWnd,IDC_CHECK2,BST_CHECKED);
				CheckDlgButton(hWnd,IDC_CHECK3,BST_UNCHECKED);
			}
			else
			{
				CheckDlgButton(hWnd,IDC_CHECK2,BST_UNCHECKED);
				CheckDlgButton(hWnd,IDC_CHECK3,BST_CHECKED);
			}
			break;
		case IDC_CHECK3:
			if(IsDlgButtonChecked(hWnd,IDC_CHECK2) == BST_CHECKED)
			{
				CheckDlgButton(hWnd,IDC_CHECK2,BST_UNCHECKED);
				CheckDlgButton(hWnd,IDC_CHECK3,BST_CHECKED);
			}
			else
			{
				CheckDlgButton(hWnd,IDC_CHECK2,BST_CHECKED);
				CheckDlgButton(hWnd,IDC_CHECK3,BST_UNCHECKED);
			}
			break;
		case IDC_CHECK4:
			if(IsDlgButtonChecked(hWnd,IDC_CHECK5) == BST_CHECKED)
			{
				CheckDlgButton(hWnd,IDC_CHECK4,BST_CHECKED);
				CheckDlgButton(hWnd,IDC_CHECK5,BST_UNCHECKED);
			}
			else
			{
				CheckDlgButton(hWnd,IDC_CHECK4,BST_UNCHECKED);
				CheckDlgButton(hWnd,IDC_CHECK5,BST_CHECKED);
			}
			break;
		case IDC_CHECK5:
			if(IsDlgButtonChecked(hWnd,IDC_CHECK4) == BST_CHECKED)
			{
				CheckDlgButton(hWnd,IDC_CHECK4,BST_UNCHECKED);
				CheckDlgButton(hWnd,IDC_CHECK5,BST_CHECKED);
			}
			else
			{
				CheckDlgButton(hWnd,IDC_CHECK4,BST_CHECKED);
				CheckDlgButton(hWnd,IDC_CHECK5,BST_UNCHECKED);
			}
			break;
		case IDC_CONFIG_OK:
			if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("Software"),0,KEY_READ,&hKey) == ERROR_SUCCESS )
			{
				if( RegCreateKeyEx(hKey,REG_FOLDER,0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hChildKey,&dwDisposition ) == ERROR_SUCCESS)
				{
					dwConvSet = 0;
					if(IsDlgButtonChecked(hWnd,IDC_CHECK2) == BST_CHECKED)
						dwConvSet &= ~STRUCT_CODE_NORMAL;
					if(IsDlgButtonChecked(hWnd,IDC_CHECK3) == BST_CHECKED)
						dwConvSet |= STRUCT_CODE_NORMAL;
					if(IsDlgButtonChecked(hWnd,IDC_CHECK4) == BST_CHECKED)
						dwConvSet |= BASECODE_FREQ_FIRST;
					if(IsDlgButtonChecked(hWnd,IDC_CHECK5) == BST_CHECKED)
						dwConvSet &= ~BASECODE_FREQ_FIRST;					

					RegSetValueEx(hChildKey,_T("ConversionSet"),0,REG_DWORD,(LPBYTE)&dwConvSet,sizeof(DWORD));
					RegCloseKey(hChildKey);
					GlobalData::Setting = dwConvSet;
				}
				RegCloseKey(hKey);
			}
			EndDialog(hWnd,TRUE);
			break;
		case IDCANCEL:
			EndDialog(hWnd,TRUE);
			break;

		default:
			return FALSE;
			break;
		}
		break;
	default:
		return FALSE;
		break;
	}
	return TRUE;
}